package com.alibaba.citrus.cr.platform.enhance.facade.service.employee;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;

import com.epoch.app.bcorder.model.dto.BaselineGetEmployeesByRelationOrgId2Request;
import com.epoch.app.bcorder.model.dto.BaselineGetEmployeesByRelationOrgIds2Request;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByOutCodes2Request;
import com.epoch.app.bcorder.model.dto.BaselineGetOrganizationByOutCodes2Response;
import com.epoch.app.bcorder.model.dto.EmployeeGetCurrentLoginResponse;
import com.epoch.app.bcorder.model.dto.EmployeeSDO;
import com.epoch.app.bcorder.model.dto.GetEmployeesByRoleCodeRequest;
import com.epoch.app.bcorder.model.dto.OmsListEmployeeAtPage2Request;
import com.epoch.app.bcorder.model.dto.RoleSDO;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.crplatformenhance.api.companyquery.service.CompanyQueryService;
import com.epoch.app.crplatformenhance.api.employeequery.dto.GetAllEmployeesByOrgIdAndRoleIdRequest;
import com.epoch.app.crplatformenhance.api.employeequery.dto.GetAllEmployeesByOrgIdAndRoleIdsRequest;
import com.epoch.app.crplatformenhance.api.employeequery.dto.GetEmployeesByOrgIdAndRoleIdEsRequest;
import com.epoch.app.crplatformenhance.api.employeequery.dto.GetEmployeesByOrgIdAndRoleIdRequest;
import com.epoch.app.crplatformenhance.api.employeequery.dto.ListEmployeeAtPageAuthRequest;
import com.epoch.app.crplatformenhance.api.employeequery.service.EmployeeQueryService;
import com.epoch.app.crplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.crplatformenhance.dto.request.IdQueryRequest;
import com.epoch.app.crplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.crplatformenhance.enums.RoleQueryTypeEnum;
import com.epoch.app.crplatformenhance.model.dto.ListEmployeeAtPageRequest;
import com.epoch.app.crplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.crplatformenhance.service.CrPlatformEnhanceService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

/**
 * @author zhoubc
 * @description: TODO
 * @date 2021/11/24 0:11
 */
@Component
@Primary
public class EmployeeQueryServiceImpl implements EmployeeQueryService {

    @Resource
    BaseDataService baseDataService;

    @Resource
    BcOrderService bcOrderService;

    @Resource
    CrPlatformEnhanceService crPlatformEnhanceService;

    @Resource
    OrganizationQueryService organizationQueryService;

    @Resource
    CompanyQueryService companyQueryService;

    @Override
    public Result<List<EmployeeSDO>> getEmployeesByOrgIdAndRoleId(GetEmployeesByOrgIdAndRoleIdRequest request) {
        List<EmployeeSDO> result = new ArrayList<>();
        List<EmployeeSDO> roleEmployeeList = new ArrayList<>();
        List<EmployeeSDO> orgEmployeeList = new ArrayList<>();

        if(StringUtil.isNotEmpty(request.getOrganizationId())){
            BaselineGetEmployeesByRelationOrgId2Request getEmployeesByOrgIdRequest = new BaselineGetEmployeesByRelationOrgId2Request();
            getEmployeesByOrgIdRequest.setId(request.getOrganizationId());
            Result<List<EmployeeSDO>> orgEmployeeResult = baseDataService.baselineGetEmployeesByRelationOrgId2(getEmployeesByOrgIdRequest);
            orgEmployeeList = orgEmployeeResult.getResult();
        }
        if(StringUtil.isNotEmpty(request.getRoleCode())){
            for(int start=0; start<=1000; start+=100){
                GetEmployeesByRoleCodeRequest getEmployeesByRoleCodeRequest = new GetEmployeesByRoleCodeRequest();
                getEmployeesByRoleCodeRequest.setCode(request.getRoleCode());
                getEmployeesByRoleCodeRequest.setStart(start);
                getEmployeesByRoleCodeRequest.setSize(100);
                Result<List<EmployeeSDO>> roleEmployeeResult = baseDataService.getEmployeesByRoleCode(getEmployeesByRoleCodeRequest);
                roleEmployeeList.addAll(roleEmployeeResult.getResult());
                if(CollectionUtils.isEmpty(roleEmployeeResult.getResult())){
                    break;
                }
            }
        }
        if(StringUtil.isBlank(request.getRoleCode()) || StringUtil.isBlank(request.getOrganizationId())){
            result.addAll(roleEmployeeList);
            result.addAll(orgEmployeeList);
            return Result.listSuccess(result, result.size());
        }

        if(CollectionUtils.isEmpty(roleEmployeeList) || CollectionUtils.isEmpty(orgEmployeeList)){
            return Result.listSuccess(result, result.size());
        }

        Map<String,EmployeeSDO> roleEmployeeMap = roleEmployeeList.stream().collect(Collectors.toMap(EmployeeSDO::getId, Function.identity(),(v1, v2)->v1));
        result = orgEmployeeList.stream().filter(x -> roleEmployeeMap.get(x.getId()) != null ).collect(Collectors.toList());
        System.out.println(result.size());

        return Result.listSuccess(result, result.size());
    }

    @Override
    public Result<List<EmployeeSDO>> getEmployeesByOrgIdAndRoleIdEs(GetEmployeesByOrgIdAndRoleIdEsRequest getEmployeesByOrgIdAndRoleIdEsRequest) {
        if(StringUtil.isBlank(getEmployeesByOrgIdAndRoleIdEsRequest.getOrganizationId())){
            throw new FacadeException(ErrorMessage.code("OTS-01-003-01-15-028"));
        }
        OmsListEmployeeAtPage2Request request = new OmsListEmployeeAtPage2Request();
        request.setRelationOrganizationIdList(Lists.newArrayList(getEmployeesByOrgIdAndRoleIdEsRequest.getOrganizationId()));
        request.setLimit(1000);
        Result<List<EmployeeSDO>> queryResult = bcOrderService.omsListEmployeeAtPage2(request);
        if(StringUtil.isBlank(getEmployeesByOrgIdAndRoleIdEsRequest.getRoleCode())){
            return queryResult;
        }
        List<EmployeeSDO> result = queryResult.getResult().stream().filter(x -> x.getRoleList()
                .stream().anyMatch(y -> getEmployeesByOrgIdAndRoleIdEsRequest.getRoleCode().equals(y.getCode()))).collect(Collectors.toList());

        return Result.listSuccess(result,result.size());
    }

    @Override
    public Result<List<EmployeeSDO>> getAllEmployeesByOrgIdAndRoleId(GetAllEmployeesByOrgIdAndRoleIdRequest request) {
        if(StringUtil.isBlank(request.getRoleCode()) || StringUtil.isBlank(request.getOrganizationId())){
            return Result.listSuccess(Lists.newArrayListWithCapacity(0), 0);
        }
        List<EmployeeSDO> roleEmployeeList = new ArrayList<>();
        List<String> orgIds = new ArrayList<>();

        // 包括当前组织在内的所有子组织id
        IdQueryRequest idQueryRequest = new IdQueryRequest();
        idQueryRequest.setId(request.getOrganizationId());
        idQueryRequest.setStart(0);
        idQueryRequest.setLimit(999);
        Result<List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO>> organizationList = organizationQueryService.getAllChildOrganizationList(idQueryRequest);
        if (CollectionUtils.isNotEmpty(organizationList.getResult())) {
            organizationList.getResult().forEach(org -> orgIds.add(org.getId()));
        }
        // 批量查询关联组织下的员工
        BaselineGetEmployeesByRelationOrgIds2Request getEmployeesByOrgIdRequest = new BaselineGetEmployeesByRelationOrgIds2Request();
            getEmployeesByOrgIdRequest.setIds(orgIds);
        Result<List<EmployeeSDO>> listResult = baseDataService.baselineGetEmployeesByRelationOrgIds2(getEmployeesByOrgIdRequest);
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            return Result.listSuccess(Lists.newArrayListWithCapacity(0), 0);
        }
        for(int start=0; start<=5000; start+=100){
            GetEmployeesByRoleCodeRequest getEmployeesByRoleCodeRequest = new GetEmployeesByRoleCodeRequest();
            getEmployeesByRoleCodeRequest.setCode(request.getRoleCode());
            getEmployeesByRoleCodeRequest.setStart(start);
            getEmployeesByRoleCodeRequest.setSize(100);
            Result<List<EmployeeSDO>> roleEmployeeResult = baseDataService.getEmployeesByRoleCode(getEmployeesByRoleCodeRequest);
            roleEmployeeList.addAll(roleEmployeeResult.getResult());
//            if(CollectionUtils.isEmpty(roleEmployeeResult.getResult())) {
//                break;
//            }
        }
        if(CollectionUtils.isEmpty(roleEmployeeList)){
            return Result.listSuccess(Lists.newArrayListWithCapacity(0), 0);
        }
        Map<String,EmployeeSDO> roleEmployeeMap = roleEmployeeList.stream().collect(Collectors.toMap(EmployeeSDO::getId, Function.identity(),(v1, v2)->v1));
        List<EmployeeSDO> sdoList = listResult.getResult().stream().filter(x -> roleEmployeeMap.get(x.getId()) != null).collect(Collectors.toList());
        return Result.listSuccess(sdoList, sdoList.size());
    }

    @Override
    public Result<List<EmployeeSDO>> getAllEmployeesByOrgIdAndRoleIds(GetAllEmployeesByOrgIdAndRoleIdsRequest request) {
        List<EmployeeSDO> result = new ArrayList<>();
        List<EmployeeSDO> roleEmployeeList = new ArrayList<>();
        List<EmployeeSDO> orgEmployeeList = new ArrayList<>();

        if(StringUtil.isNotEmpty(request.getOrganizationId())){
            BaselineGetEmployeesByRelationOrgId2Request getEmployeesByOrgIdRequest = new BaselineGetEmployeesByRelationOrgId2Request();
            getEmployeesByOrgIdRequest.setId(request.getOrganizationId());
            Result<List<EmployeeSDO>> orgEmployeeResult = baseDataService.baselineGetEmployeesByRelationOrgId2(getEmployeesByOrgIdRequest);
            orgEmployeeList = orgEmployeeResult.getResult();
        }

        List<EmployeeSDO> distinctRoleEmployeeList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(request.getRoleCodes())){
            for(String code:(List<String>)request.getRoleCodes()){
                for(int start=0; start<=1000; start+=100){
                    GetEmployeesByRoleCodeRequest getEmployeesByRoleCodeRequest = new GetEmployeesByRoleCodeRequest();
                    getEmployeesByRoleCodeRequest.setCode(code);
                    getEmployeesByRoleCodeRequest.setStart(start);
                    getEmployeesByRoleCodeRequest.setSize(100);
                    Result<List<EmployeeSDO>> roleEmployeeResult = baseDataService.getEmployeesByRoleCode(getEmployeesByRoleCodeRequest);
                    roleEmployeeList.addAll(roleEmployeeResult.getResult());
                    if(CollectionUtils.isEmpty(roleEmployeeResult.getResult())){
                        break;
                    }
                }
            }

            roleEmployeeList.stream().forEach(x->{
                if(!distinctRoleEmployeeList.contains(x)){
                    distinctRoleEmployeeList.add(x);
                }
            });
        }

        //查询条件， 只有角色或只有组织的情况
        if((CollectionUtils.isEmpty(request.getRoleCodes()) || StringUtil.isBlank(request.getOrganizationId()))){
            result.addAll(distinctRoleEmployeeList);
            result.addAll(orgEmployeeList);
            return Result.listSuccess(result, result.size());
        }

        //查询条件全有
        //查询无数据的情况 取不到交集
        if(CollectionUtils.isEmpty(roleEmployeeList) || CollectionUtils.isEmpty(orgEmployeeList)){
            return Result.listSuccess(result, result.size());
        }

        // 组织下员工 与角色下员工的交集
        Map<String,EmployeeSDO> roleEmployeeMap = distinctRoleEmployeeList.stream().collect(Collectors.toMap(EmployeeSDO::getId, Function.identity(),(v1, v2)->v1));
        result = orgEmployeeList.stream().filter(x -> roleEmployeeMap.get(x.getId()) != null).collect(Collectors.toList());
        return Result.listSuccess(result, result.size());
    }

    @Override
    public Object listEmployeeAtPageAuth(ListEmployeeAtPageAuthRequest listEmployeeAtPageAuthRequest) {
        List<String> queryOrganizationIdList = listEmployeeAtPageAuthRequest.getRelationOrganizationIdList();
        //获取登录员工组织下的所有组织
        if(CollectionUtils.isEmpty(queryOrganizationIdList)){
            EmployeeGetCurrentLoginResponse loginUser = bcOrderService.employeeGetCurrentLogin();
            IdQueryRequest request = new IdQueryRequest();
            request.setId(loginUser.getRelatedOrganizationId());
            Result<List<OrganizationSDO>> allChildOrgResult = organizationQueryService.getAllChildOrganizationList(request);
            if(allChildOrgResult !=null && CollectionUtils.isNotEmpty(allChildOrgResult.getResult())){
                queryOrganizationIdList = allChildOrgResult.getResult().stream().map(x->x.getId()).collect(Collectors.toList());
            }
        }

        //分页查询员工ES
        ListEmployeeAtPageRequest pageQueryEmployeesRequest = ListEmployeeAtPageRequest.builder()
                .relationOrganizationIdList(queryOrganizationIdList)
                .searchType(listEmployeeAtPageAuthRequest.getSearchType())
                .searchValue(listEmployeeAtPageAuthRequest.getSearchValue())
                .status(listEmployeeAtPageAuthRequest.getStatus())
                .start(listEmployeeAtPageAuthRequest.getStart())
                .limit(listEmployeeAtPageAuthRequest.getLimit())
                .build();
        Map queryResult = (Map)crPlatformEnhanceService.listEmployeeAtPage(pageQueryEmployeesRequest);
        Map result = (Map) queryResult.get("result");
        Object content = result.get("content");
        List<EmployeeSDO> employeelist = JSONArray.parseArray(JSONObject.toJSONString(content),EmployeeSDO.class);
        if(CollectionUtils.isEmpty(employeelist)){
            return queryResult;
        }
        //获取蒙牛订单所有组织
        Map<String,OrganizationSDO> mnAllOrg = getMnOrderAllOrg();
        for (EmployeeSDO sdo : employeelist) {
            //员工所属系统
            if(CollectionUtils.isNotEmpty(sdo.getRoleList())){
                StringBuilder sys = new StringBuilder();
                Set<String> belongOrganizationIds = sdo.getRoleList().stream().map(RoleSDO::getBelongOrganizationId).collect(Collectors.toSet());
                if(belongOrganizationIds.contains("1")){
                    sys.append("订单平台;");
                }
                if(belongOrganizationIds.contains("2") || belongOrganizationIds.contains("3")|| belongOrganizationIds.contains("4") || belongOrganizationIds.contains("5")){
                    sys.append("双渠道;");
                }
                if(belongOrganizationIds.contains("6")){
                    sys.append("蒙牛一盘货;");
                }
                sdo.setSys(sys.toString());
            }

            List<com.epoch.app.bcorder.model.dto.OrganizationSDO> employeeOrgs = sdo.getOrganizationList();
            if(CollectionUtils.isEmpty(employeeOrgs)){
                continue;
            }
            com.epoch.app.bcorder.model.dto.OrganizationSDO employeeOrg = employeeOrgs.get(0);
            //蒙牛员工展示员工所属分子公司
            if(mnAllOrg.get(employeeOrg.getId()) != null){
                if(employeeOrg.getType() > OrganizationTypeEnum.COMPANY.getCode()){
                    IdQueryRequest queryTopOrgList = new IdQueryRequest();
                    queryTopOrgList.setId(employeeOrg.getId());
                    queryTopOrgList.setType(OrganizationTypeEnum.COMPANY.getCode());
                    Result<List<OrganizationSDO>> orgResult = organizationQueryService.getTopOrganizationList(queryTopOrgList);
                    if (orgResult!=null && CollectionUtils.isNotEmpty(orgResult.getResult())) {
                        OrganizationSDO orgCompany = orgResult.getResult().get(orgResult.getResult().size()-1);
                        sdo.setOrgBussinessUnitCode(orgCompany.getCode());
                        sdo.setOrgBussinessUnitName(orgCompany.getName());
                    }
                }else {
                    sdo.setOrgBussinessUnitCode(employeeOrg.getCode());
                    sdo.setOrgBussinessUnitName(employeeOrg.getName());
                }
            }
        }
        result.put("content",employeelist);
        return queryResult;
    }

    private Map<String,OrganizationSDO> getMnOrderAllOrg(){
        BaselineGetOrganizationByOutCodes2Response orgResponse = baseDataService.baselineGetOrganizationByOutCodes2(
                BaselineGetOrganizationByOutCodes2Request.builder().
                        outCodes(Lists.newArrayList("6000"))
                        .build());
        if(CollectionUtils.isNotEmpty(orgResponse.getResult())){
            com.epoch.app.bcorder.model.dto.OrganizationSDO org = orgResponse.getResult().get(0);
            IdQueryRequest request = new IdQueryRequest();
            request.setId(org.getId());
            request.setType(OrganizationTypeEnum.SALES_DEPARTMENT.getCode());
            Result<List<OrganizationSDO>> result = organizationQueryService.getAllChildOrganizationList(request);
            if(CollectionUtils.isNotEmpty(result.getResult())){
                Map<String,OrganizationSDO> allOrgMap = result.getResult().stream().collect(Collectors.toMap(OrganizationSDO::getId, Function.identity(),(v1, v2)->v1));
                allOrgMap.put("1",new OrganizationSDO());
                return allOrgMap;
            }
        }
        return new HashMap<>();
    }

}
